<?php

namespace app\admin\command;

use think\Config;
use think\console\Command;
use think\console\Input;
use think\console\input\Option;
use think\console\Output;
use think\Exception;

use app\common\library\FSHelper;

use app\admin\model\Gateway;
use app\admin\model\Task;
use app\admin\model\TaskJob;

class StatusUpdater extends Command {
    
    protected $statusUpdateInterval = 10000; //单位：毫秒

    protected $agent_name_suffix = '@default';

    protected $fsHelper = null;

    protected function configure() {
        $this->setName('statusupdater')
             ->setDescription('Update Queue Agent status && Task statisticscalls intermittently');
    }
    
    protected function execute(Input $input, Output $output) {
        $loop = 0;
        while (1) {
            $loop++;
            $loop = ($loop >= PHP_INT_MAX) ? 1 : $loop;
            echo "\r\n------ StatusUpdater Execute Loop: {$loop} ------\r\n";
            if ($this->fsHelper == null) {
                echo "------ ------ Initialize FSHelper\r\n";
                $this->fsHelper = new FSHelper();
            }
            $executeDuration = $this->updateAgentStatus();
            $executeDuration+= $this->updateTaskStatus();
            if (($loop % 10) == 0) {
                echo "------ ------ Disconnect ESL for every 10 loops\r\n";
                $this->fsHelper->disconnect();
                $this->fsHelper = null;
            }
            $time_left = ($this->statusUpdateInterval - $executeDuration) > 0 ? ($this->statusUpdateInterval - $executeDuration) : 0;
            usleep($time_left * 1000);
        }
    }

    protected function updateAgentStatus() {
        $beginTime = time();

        $db = Db();
        $result = $db->query('select * from agents where status in (?, ?)', ['Available', 'Available (On Demand)']);
        foreach ($result as $one) {
            $extension = str_replace($this->agent_name_suffix, '', $one['name']);
            //echo "{$extension}\r\n";
            $result2 = $db->query('select count(*) as count from sip_registrations where sip_user = ?', [$extension]);
            $count = $result2[0]['count'];
            if ($count <= 0) {
                $db->execute('update agents set status = ? where name = ?', ['On Break', $extension . $this->agent_name_suffix]);
            }
        }
        $executeDuration = time() - $beginTime;
        return $executeDuration;
    }

    protected function updateTaskStatus() {
        $beginTime = time();
       
        $db = Db(); 
        $where = array();
        $where['state'] = array('=', '1');
        $taskList = Task::where($where)->order('id desc')->select();
        foreach ($taskList as $task) {
            $result = $db->query('select count(*) as count from fa_task_job where tid=?', [$task->id]);
            $task->total_count = $result[0]['count'];
            //$result = $db->query('select count(*) as count from fa_task_job where tid=? and called=1 and callstate in(\'success\', \'fail\')', [$task->id]);
            $result = $db->query('select count(*) as count from fa_task_job where tid=? and called=1', [$task->id]);
            $task->done_count = $result[0]['count'];
            if ($task->callback_type == 'ivr') {
                $result = $db->query('select count(*) as count from fa_task_job where tid=? and called=1 and ivrstate in(\'started\', \'finished\')', [$task->id]);
            } else {
                $result = $db->query('select count(*) as count from fa_task_job where tid=? and called=1 and queuestate in(\'recepted\')', [$task->id]);
            }
            $task->success_count = $result[0]['count'];
            $result = db()->query('select count(*) as count from limit_data where `realm`=? and `id`=?', ['task', $task->id]);
            $task_running_count = $result[0]['count'];
            $task->fail_count = $task->done_count - $task->success_count - $task_running_count;
            $task->fail_count = $task->fail_count > 0 ? $task->fail_count : 0;
            if ($task->total_count != 0) {
                $task->progress = sprintf('%.0f%%', $task->done_count * 100 / $task->total_count);
            } else {
                $task->progress = '0%';
            }
            /*$where2 = array();
            $where2['tid'] = $task->id;
            $where2['called'] = 0;
            $job = TaskJob::where($where2)->find();*/
            //if (empty($job)) {
            if ($task->progress == '100%') {
                //check for last task job finished
                if ($task_running_count <= 0) {
                    $task->state = 2;
                    echo "removeCallbackForTask: task->id: {$task->id}\r\n";
                    $this->fsHelper->removeCallbackForTask($task->id);
                }
            }
            $task->save();
        }

        $executeDuration = time() - $beginTime;
        return $executeDuration;
    }
    
}
